package com.sikaryofficial.backend.manager;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sikaryofficial.backend.config.StoreCommentConfig;
import com.sikaryofficial.backend.constant.MyStatisticsTypeEnum;
import com.sikaryofficial.backend.domain.dto.req.store.StoreCommentListReq;
import com.sikaryofficial.backend.domain.dto.req.store.StoreCommentReplySaveReq;
import com.sikaryofficial.backend.domain.dto.req.store.StoreCommentSaveReq;
import com.sikaryofficial.backend.domain.dto.resp.StoreCommentReplyDTO;
import com.sikaryofficial.backend.domain.dto.resp.StoreCommentReplyResp;
import com.sikaryofficial.backend.domain.dto.resp.StoreCommentResp;
import com.sikaryofficial.backend.domain.dto.resp.information.ArticleEvaluateReplyDTO;
import com.sikaryofficial.backend.domain.entity.StoreComment;
import com.sikaryofficial.backend.domain.entity.StoreCommentReply;
import com.sikaryofficial.backend.domain.mapping.StoreCommentMapping;
import com.sikaryofficial.backend.domain.vo.EvaluateReplyCount;
import com.sikaryofficial.backend.domain.vo.store.CommentReplyCount;
import com.sikaryofficial.backend.service.IAttachmentService;
import com.sikaryofficial.backend.service.IStoreCommentLimitService;
import com.sikaryofficial.backend.service.IStoreCommentReplyService;
import com.sikaryofficial.backend.service.IStoreCommentService;
import com.sikaryofficial.backend.service.statistics.MyStatisticsEvent;
import com.sikaryofficial.backend.service.statistics.MyStatisticsProcessor;
import com.sikaryofficial.backend.service.user.UserCacheService;
import com.sikaryofficial.common.core.exception.ServiceException;
import com.sikaryofficial.common.core.utils.ip.IpUtils;
import com.sikaryofficial.common.redis.service.RedisService;
import com.sikaryofficial.common.security.utils.SecurityUtils;
import com.sikaryofficial.system.api.model.att.AttachmentResp;
import com.sikaryofficial.system.api.model.ip.IpLocationVO;
import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author : wuweihong
 * @desc : TODO  请填写你的功能描述
 * @date : 2025-08-21
 */

@Service
public class StoreCommentManager {

	@Autowired
	private IStoreCommentService storeCommentService;

	@Autowired
	private IAttachmentService attachmentService;

	@Autowired
	private UserCacheService userCacheService;

	@Autowired
	private IStoreCommentReplyService storeCommentReplyService;

	@Autowired
	private Ip2LocationManager ip2LocationManager;

	@Autowired
	private IStoreCommentLimitService storeCommentLimitService;

	@Autowired
	private MyStatisticsProcessor myListener;

	@Autowired
	private StoreCommentConfig storeCommentConfig;

	/**
	 * 保存店铺评论
	 * @param storeCommentReq 店铺评论入参
	 */
	public void saveStoreComment(StoreCommentSaveReq storeCommentReq) {
		boolean allowComment = storeCommentLimitService.allowComment(storeCommentReq.getStoreId());
		if (!allowComment) {
			throw new ServiceException("评论频率过快，请稍后再试");
		}
		Long userId = SecurityUtils.getUserId();
		StoreComment storeComment = StoreCommentMapping.INSTANCE.coverToStoreComment(storeCommentReq);
		ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		assert  attributes != null;
		HttpServletRequest request = attributes.getRequest();
		String ip = IpUtils.getIpAddr(request);
		IpLocationVO ipLocationVO = ip2LocationManager.getGeographyInfo(ip);
		storeComment.setCreatedBy(userId);
		storeComment.setCreatedName(userCacheService.getSignUserNickName(userId));
		storeComment.setCountry(ipLocationVO.getCountryName());
		storeComment.setArea(ipLocationVO.getArea());
		storeComment.setCity(ipLocationVO.getCity());
		storeCommentService.save(storeComment);
		attachmentService.saveAttachmentList(storeComment.getStoreCommentId(), storeCommentReq.getAttachmentList(), userId);

		// 3.1 添加店铺评价统计
		myListener.addMyStatistics(new MyStatisticsEvent(MyStatisticsTypeEnum.COMMENTS_STORE.getBusinessType(), userId, storeComment.getStoreCommentId()));
		// 3.2 添加该店铺评论对应的评论统计
		myListener.addMyStatistics(new MyStatisticsEvent(MyStatisticsTypeEnum.COMMENTS_STORE_COUNT.getBusinessType(), userId, storeComment.getStoreId()));

	}

	/**
	 * 保存评论回复
	 * @param storeCommentReplySaveReq 评论回复入参
	 */
	public void saveStoreCommentReply(StoreCommentReplySaveReq storeCommentReplySaveReq) {
		boolean allowComment = storeCommentLimitService.allowComment(storeCommentReplySaveReq.getStoreId());
		if (!allowComment) {
			throw new ServiceException("评论频率过快，请稍后再试");
		}
		StoreCommentReply storeCommentReply = StoreCommentMapping.INSTANCE.coverToStoreCommentReply(storeCommentReplySaveReq);
		storeCommentReply.setCreatedBy(SecurityUtils.getUserId());
		storeCommentReply.setCreatedName(SecurityUtils.getUsername());
		storeCommentReplyService.save(storeCommentReply);
		attachmentService.saveAttachmentList(storeCommentReply.getStoreCommentReplyId(), storeCommentReplySaveReq.getAttachmentList(), SecurityUtils.getUserId());
	}

	/**
	 * 分页获取店铺的所有评论
	 * @return
	 */
	public IPage<StoreCommentResp> getStoreCommentPage(StoreCommentListReq storeCommentListReq) {
		IPage<StoreCommentResp> storeCommentRespIPage = storeCommentService.findStoreCommentPage(new Page<>(storeCommentListReq.getPageNum(), storeCommentListReq.getPageSize()), storeCommentListReq);
		buildExtendData(storeCommentRespIPage.getRecords());
		buildReplyData(storeCommentRespIPage.getRecords());
		return storeCommentRespIPage;
	}

	private void buildExtendData(List<StoreCommentResp> storeCommentRespList) {
		List<Long> commentIdList = storeCommentRespList.stream().map(StoreCommentResp::getStoreCommentId).collect(Collectors.toList());
		Map<Long, List<AttachmentResp>> attachmentRespMap = attachmentService.getAttachmentByIds(commentIdList);
		storeCommentRespList.forEach(storeCommentResp -> {
			storeCommentResp.setAttachments(attachmentRespMap.get(storeCommentResp.getStoreCommentId()));
		});
	}

	private void buildReplyData(List<StoreCommentResp> storeCommentRespList) {
		List<Long> commentIdList = storeCommentRespList.stream().map(StoreCommentResp::getStoreCommentId).collect(Collectors.toList());
		List<CommentReplyCount> commentReplyCountList = storeCommentReplyService.countByCommentId(commentIdList, SecurityUtils.getUserId());
		Map<Long, Integer> commentReplyCountMap = commentReplyCountList.stream().filter(item -> Objects.nonNull(item.getReplyCount()))
				.collect(Collectors.toMap(CommentReplyCount::getCommentId, CommentReplyCount::getReplyCount, (k1, k2) -> k1));
		storeCommentRespList.forEach(item -> item.setReplyCount(MapUtils.getObject(commentReplyCountMap, item.getStoreCommentId())));

		// 填充每条评论下 回复列表的第1页数据-7条
		List<StoreCommentReplyDTO> replyList = storeCommentReplyService.queryByCommentId(commentIdList, storeCommentConfig.getLimitNum(), SecurityUtils.getUserId());
		Map<Long, List<StoreCommentReplyDTO>> replyListMap = replyList.stream().collect(Collectors.groupingBy(StoreCommentReplyDTO::getStoreCommentId));
		storeCommentRespList.forEach(item -> item.setReplyList(MapUtils.getObject(replyListMap, item.getStoreCommentId())));
	}

}
